package RoutingManagement

import (
	/*
		系统包
	*/
	"log"
	"net/http"
	"regexp"
	"time"
	/*
	   框架API包
	*/
	"../DirDataAPI"
)

// 定义类型
/*
 名称
	路由表页结构体
 参数
  验证身份
	Gmlevel			访问权限	(false 普通用户	true 会员用户)(非管理员路由下有效)(用户权限验证)
	Privilege		权限设定	(false 不需要权限	true 需要权限)(非管理员路由下有效)(用于登陆验证)
	// API权限限定
	Controller		最高权限	(false 不需要权限	true 只能管理员)
	----------------------
  访问设置
	AccessMethod 	访问方法 	(false 绝对路径	true 正则匹配)
  处理函数
	HInheritance 	继承处理函数
	EInheritance	错误继承函数
*/
type AccessClass struct {
	// 权限设置
	Gmlevel    bool
	Privilege  bool
	Controller bool
	// 访问设置
	AccessMethod bool
	// 继承处理函数
	HInheritance func(http.ResponseWriter, *http.Request)
	EInheritance func(http.ResponseWriter, *http.Request)
}

/*
 名称
	用户链结构体
 参数
	possess	 用户权限等级	(false 普通用户	true 会员)
	regdate	 注册时间		(用于判断生存周期 类型时间戳)
	position 身份信息		(唯一标示用于长时间数据库查找,用户名与密码的唯一匹配码)
->说明
	用户分为普通用户与会员根据用户类型允许访问特定的资源
*/
type Userinfo struct {
	Possess  bool
	Regdate  int
	Position string
}

// 全局变量
var Access map[string]AccessClass   //路由表
var TheUserList map[string]Userinfo //用户链
var StaticResource string
var server http.Server

// 路由解析 接口类型定义
type MyHandle struct{}

/*
   框架初始化函数
*/
func InItRouting(Addr string) {
	//静态资源目录
	StaticResource = DirDataAPI.GetCurrentPath()
	StaticResource += "StaticResource\\WrongEcho\\"
	//-> 创建路由数组
	Access = make(map[string]AccessClass)
	//-> 创建用户数组
	TheUserList = make(map[string]Userinfo)
	//-> 初始化通信
	server = http.Server{
		// 端口
		Addr: Addr,
		// 路由解析函数
		Handler: &MyHandle{},
		// 超时
		ReadTimeout: 6 * time.Second,
	}
}

/*
   运行网站
*/
func RunWebsite() {
	//	开始监视
	err := server.ListenAndServe()
	if err != nil {
		// 记录错误日志
		log.Fatal(err)
	}
}

/*
	路由表匹配函数
*/
func (*MyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var ok bool
	/*
	 循环读取路由表,判断出符合的路由
	*/
	for key, member := range Access {
		// 用户区路由默认访问
		if member.AccessMethod {
			//使用正则匹配
			ok, _ = regexp.MatchString(key, r.URL.String())
		} else {
			//绝对路径访问
			if key == r.URL.String() {
				ok = true
			}
		}
		// 访问路由
		if ok {
			if member.Controller {
				// 过滤管理员API路由
				DirDataAPI.SendFile(w, StaticResource, "403-ROOT.html")
			} else {
				if member.Privilege {
					// 认证请求的合法性
					URLkey := DirDataAPI.URLkey(r.URL.String())
					use, useok := TheUserList[URLkey]
					if useok {
						if member.Gmlevel {
							if use.Possess == false {
								DirDataAPI.SendFile(w, StaticResource, "403-Member.html")
								goto AccessViolation
							}
						}
						member.HInheritance(w, r)
						return
					}
					/*
						用户标示不存在
						非法的用户访问
					*/
					DirDataAPI.SendFile(w, StaticResource, "403.html")
				AccessViolation:
					/*
						记录错误日志
					*/
					if member.EInheritance != nil {
						member.EInheritance(w, r)
					}
					return
				} else {
					/*
						路径验证正确返回给路由继续处理
					*/
					member.HInheritance(w, r)
					return
				}
			}
		}
	}
	/*
		错误处理过程
	*/
	DirDataAPI.SendFile(w, StaticResource, "404.html")
}
